package ink.wbc.easyrule;

import ink.wbc.drools.entity.User;
import ink.wbc.easyrule.rule.LotteryCompositeRule;
import ink.wbc.easyrule.rule.LotteryListener;
import ink.wbc.easyrule.rule.LotteryRule;
import org.jeasy.rules.api.Facts;
import org.jeasy.rules.api.Rule;
import org.jeasy.rules.api.Rules;
import org.jeasy.rules.api.RulesEngineParameters;
import org.jeasy.rules.core.DefaultRulesEngine;
import org.jeasy.rules.core.RuleBuilder;
import org.jeasy.rules.mvel.MVELRule;
import org.jeasy.rules.spel.SpELRule;
import org.jeasy.rules.spel.SpELRuleFactory;
import org.jeasy.rules.support.composite.CompositeRule;
import org.jeasy.rules.support.composite.UnitRuleGroup;
import org.jeasy.rules.support.reader.YamlRuleDefinitionReader;

import java.io.File;
import java.io.FileReader;

/**
 * @author wbc
 * @date 2021/09/15
 * @desc
 **/
public class LotteryRuleMain {

    public static void main(String[] args) {
        User user = new User();
        user.setMoney(200);
        user.setVipFlag(1);

        Facts facts = new Facts();
        facts.put("user", user);

        RulesEngineParameters parameters = new RulesEngineParameters().priorityThreshold(1);
        DefaultRulesEngine rulesEngine = new DefaultRulesEngine(parameters);

        // 注册监听器
        rulesEngine.registerRuleListener(new LotteryListener());
        // 注册规则
        Rules rules = new Rules();
//        rules.register(new LotteryRule());
//        rules.register(fluentRule());
//        rules.register(mvelRule());
//        rules.register(spElRule());
//        rules.register(yamlRule());

        // 组合规则示例
        LotteryCompositeRule lotteryCompositeRule = new LotteryCompositeRule(new LotteryCompositeRule.VipRule(), new LotteryCompositeRule.MoneyRule());
        rules.register(lotteryCompositeRule);

        rulesEngine.fire(rules, facts);
        System.out.println("是否能够抽奖:" + user.getAllowLotteryFlag().equals(1));
    }

    public static Rule fluentRule() {
        return new RuleBuilder()
                .name("fluent lottery rule")
                .description("链式抽奖规则")
                .priority(2)
                .when(f -> {
                    User user = f.get("user");
                    return user.getMoney() >= 100;
                })
                .then(f -> {
                    System.out.println("满足抽奖条件");
                    User user = f.get("user");
                    user.setAllowLotteryFlag(1);
                })
                .build();
    }

    public static Rule mvelRule() {
        return new MVELRule()
                .name("mvel lottery rule")
                .description("mvel表达式创建规则")
                .priority(3)
                .when("user.getMoney() >=100")
                .then("user.setAllowLotteryFlag(1)");
    }

    public static Rule spElRule() {
        return new SpELRule()
                .name("SpEL lottery rule")
                .description("SpEl表达式创建规则")
                .priority(4)
                .when("#{['user'].money > 2}")
                .then("#{['user'].setAllowLotteryFlag(1)}");
    }

    public static Rule yamlRule() {
        SpELRuleFactory spELRuleFactory = new SpELRuleFactory(new YamlRuleDefinitionReader());
        File ruleFile = new File("src/main/resources/rules/lottery.yml");
        try {
            return spELRuleFactory.createRule(new FileReader(ruleFile));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}
